/**
 * 
 */
package it.gommonauti.quiz.patente.app;

import it.gommonauti.patenti.entity.Image;
import it.gommonauti.patenti.entity.MainQuestion;
import it.gommonauti.patenti.entity.SubQuestion;
import it.gommonauti.patenti.entity.UserResponse;

import java.util.ArrayList;
import java.util.Stack;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.ScrollView;
import android.widget.TextView;

/**
 *  
 * @author Francesco Stallone ( f.stallone73@gmail.com ).
 * 
 * Application base activity.
 *
 */
public abstract class QuizActivity extends BaseActivity {

	/**
	 * Timer handler
	 */
	private Handler timerHandler;

	/**
	 * Max time in second
	 */
	private int maxTimeInSeconds;

	/**
	 * Elapsed time.
	 */
	long elapsedTime;

	/**
	 * Chrono text view.
	 */
	private TextView chronoTextView = null;
	
	/**
	 * Fails counter text view
	 */
	private TextView failsCounterTextView;

	/**
	 * Id question text view
	 */
	private TextView idQuestionTextView;
	
	/**
	 * Category text view
	 */
	private TextView categoryTextView;
	
	/**
	 * Question counter tet view.
	 */
	private TextView questionCounterTextView;
	
	/**
	 * Question counter.
	 */
	private int questionCounter = 0;
	
	
	/**
	 * Success counter text view
	 */
	private TextView successCounterTextView;

	/**
	 * No response counter text view
	 */
	private TextView noResponseCounterTextView;

	/**
	 * Image view
	 */
	private ImageView mainQuestionImageView;

	/**
	 * Not available String
	 */
	private String naString;

	/**
	 * True String
	 */
	private String trueString;

	/**
	 * False String.
	 */
	private String falseString;

	/**
	 * Stack of previous main question.
	 */
	private Stack<MainQuestion> mainQuestionPreviousStack;

	/**
	 * Stack of next main question.
	 */
	private Stack<MainQuestion> mainQuestionNextStack;

	/**
	 * Fails counter
	 */
	private long failsCounter = 0;

	/**
	 * Success counter
	 */
	private long successCounter = 0;

	/**
	 * No response counter
	 */
	private long noResponseCounter = 0;

	/**
	 * Button to load next question
	 */
	private Button nextButton = null;

	/**
	 * Button to load previous question
	 */
	private Button previousButton = null;

	/**
	 * Matrix of radio button possible response.
	 */
	private RadioButton[][] userSubQuestionsResponseMatrix = null;

	/**
	 * The main question.
	 */
	private MainQuestion mainQuestion = null;

	/**
	 * SubQuestion text view list.
	 */
	private TextView[] subQuestionTextViewList = null;

	/**
	 * Radio Group sub question list.
	 */
	private RadioGroup subQuestionRadioGroupList[] = null; 

	/**
	 * The main layout.
	 */
	private LinearLayout mainLinearLayout = null;

	/**
	 * Main scroll view.
	 */
	private ScrollView mainScrollView = null;

	/**
	 * Main question text view.
	 */
	private TextView mainQuestionTextView = null;

	/**
	 * Create here you first and next MainQuestion.
	 */
	protected abstract MainQuestion loadNextMainQuestion();

	/**
	 * Previous button on click listener.
	 */
	private View.OnClickListener previousButtonOnClickHandler = new View.OnClickListener() {
		public void onClick(View v) {

			onPreviousButtonClick(v);

		}		
	};

	/**
	 * Next button on click listener.
	 */
	private View.OnClickListener nextButtonOnClickHandler = new View.OnClickListener() {
		public void onClick(View v) {

			onNextButtonClick(v);

		}		
	};

	/*
	 * To estabilish if is a new or previous question.
	 */
	private boolean isNewQuestion(){

		return mainQuestionNextStack.isEmpty();
	}

	/* (non-Javadoc)
	 * @see android.app.Activity#onCreate(android.os.Bundle)
	 */
	@Override
	protected final void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);		

		naString = getString(R.string.strNotAvailable); 

		trueString = getString(R.string.strTrue);

		falseString = getString(R.string.strFalse);

		mainQuestionPreviousStack = new Stack<MainQuestion>();

		mainQuestionNextStack = new Stack<MainQuestion>();

		inizialize();

		maxTimeInSeconds = getMaxTimeInSeconds();

		questionCounter++;
		mainQuestion = loadNextMainQuestion();

		if(mainQuestion != null){
			ArrayList<SubQuestion> subQuestionList = mainQuestion.getSubQuestions();
			if (subQuestionList != null) noResponseCounter += subQuestionList.size();
		}

		createUserInterface();

		elapsedTime = 0;
		timerHandler = new Handler();
		timerHandler.postDelayed(updateTimeTask, 500);

	} 

	/**
	 * Max time in seconds to complete activity.
	 * 
	 * -1 if no time limit.
	 */
	protected abstract int getMaxTimeInSeconds();

	/**
	 * Initializa here your object and variables.
	 */
	protected abstract void inizialize() ;

	/**
	 * load main question and draw user interface. 
	 */
	private void createUserInterface() {

		// TODO : TEST IT
		if (mainQuestion == null){

			Log.d(getDebugTag(), "create" + "start next activity");

			startActivity(getNextIntent());
		} else {


			mainScrollView = new ScrollView(this);
			mainLinearLayout = new LinearLayout(this);
			mainLinearLayout.setOrientation(LinearLayout.VERTICAL);
			mainScrollView.addView(mainLinearLayout);
			this.setContentView(mainScrollView);

			chronoTextView = new TextView(this);
			//chronoTextView.setText("TODO: elapsed time" );
			mainLinearLayout.addView(chronoTextView);

			questionCounterTextView = new TextView(this);
			// TODO: esternalizzare
			questionCounterTextView.setText("DOMANDA NUMERO : " + String.valueOf(questionCounter));
			//failsCounterTextView.setTextColor(Color.RED);
			mainLinearLayout.addView(questionCounterTextView);
			
			idQuestionTextView = new TextView(this);
			// TODO: esternalizzare
			String idQuestion = mainQuestion == null ? "" :  String.valueOf(mainQuestion.getId());  
			idQuestionTextView.setText("ID DOMANDA : " + idQuestion);
			//failsCounterTextView.setTextColor(Color.RED);
			mainLinearLayout.addView(idQuestionTextView);
			
			categoryTextView = new TextView(this);
			// TODO: esternalizzare
			String category = mainQuestion == null && mainQuestion.getParent() != null ? "" :  String.valueOf(mainQuestion.getParent().getDescription());  
			categoryTextView.setText("CATEGORIA : " + category);
			//failsCounterTextView.setTextColor(Color.RED);
			mainLinearLayout.addView(categoryTextView);
			
			failsCounterTextView = new TextView(this);
			// TODO: esternalizzare
			failsCounterTextView.setText("ERRORI : " + String.valueOf(failsCounter));
			failsCounterTextView.setTextColor(Color.RED);
			mainLinearLayout.addView(failsCounterTextView);
			
			noResponseCounterTextView = new TextView(this);
			// TODO: esternalizzare
			noResponseCounterTextView.setText("NON RISPOSTE : " + String.valueOf(noResponseCounter));
			noResponseCounterTextView.setTextColor(Color.YELLOW);
			mainLinearLayout.addView(noResponseCounterTextView);
			
			successCounterTextView = new TextView(this);
			// TODO: esternalizzare
			successCounterTextView.setText("ESATTE : " + String.valueOf(successCounter) + System.getProperty("line.separator"));
			successCounterTextView.setTextColor(Color.GREEN);
			mainLinearLayout.addView(successCounterTextView);
			
			Image mainQuestionImage = mainQuestion.getImage();
			if(mainQuestionImage != null) {

				Bitmap mainQuestionImageBitmap = mainQuestionImage.getBitmap();

				if (mainQuestionImageBitmap == null ||  mainQuestionImageBitmap.getWidth() == -1 || mainQuestionImageBitmap.getHeight() == -1){
					
					mainQuestionImageBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.logo_385_65);
					
				}
				
				if( mainQuestionImageBitmap != null &&  mainQuestionImageBitmap.getWidth() != -1 && mainQuestionImageBitmap.getHeight() != -1 ){

					mainQuestionImageView = new ImageView(this);
					mainQuestionImageView.setImageBitmap(mainQuestionImageBitmap);
					mainLinearLayout.addView(mainQuestionImageView);

				}
			} 

			//Typeface tf = Typeface.createFromAsset(getAssets(), "ASTRO867.TTF");
			
			mainQuestionTextView = new TextView(this);
			mainQuestionTextView.setText(System.getProperty("line.separator")  + mainQuestion.getDescription());
			mainQuestionTextView.setTextColor(Color.rgb(3, 96, 176));
			mainQuestionTextView.setTypeface(null, Typeface.BOLD);
			mainLinearLayout.addView(mainQuestionTextView);

			ArrayList<SubQuestion> subQuestionList = mainQuestion.getSubQuestions();

			if(subQuestionList != null){
				int subQuestionCount = subQuestionList.size();
				userSubQuestionsResponseMatrix = new RadioButton[subQuestionCount][3];
				subQuestionRadioGroupList = new RadioGroup[subQuestionCount];
				subQuestionTextViewList = new TextView[subQuestionCount];
				for(int i = 0; i < subQuestionCount; i++) {

					SubQuestion sq = subQuestionList.get(i);

					subQuestionTextViewList[i] = new TextView(this);
					subQuestionTextViewList[i].setText(sq.getDescription());
					subQuestionTextViewList[i].setTextColor(Color.WHITE);
					mainLinearLayout.addView(subQuestionTextViewList[i]);

					subQuestionRadioGroupList[i] = new RadioGroup(this);
					subQuestionRadioGroupList[i].setOrientation(LinearLayout.HORIZONTAL);

					subQuestionRadioGroupList[i].setTag(sq);
					OnClickListener radio_listener = new OnClickListener() {
						public void onClick(View v) {
							onRadioButtonClick(v);
						}			
					};

					mainLinearLayout.addView(subQuestionRadioGroupList[i]);



					userSubQuestionsResponseMatrix[i][0] = new RadioButton(this);
					userSubQuestionsResponseMatrix[i][0].setText(naString);
					userSubQuestionsResponseMatrix[i][0].setOnClickListener(radio_listener);
					userSubQuestionsResponseMatrix[i][0].setTag(UserResponse.NOT_AVAILABE);			
					userSubQuestionsResponseMatrix[i][0].setTextColor(Color.WHITE);
					userSubQuestionsResponseMatrix[i][0].setEnabled(true);
					subQuestionRadioGroupList[i].addView(userSubQuestionsResponseMatrix[i][0]);

					userSubQuestionsResponseMatrix[i][1] = new RadioButton(this);
					userSubQuestionsResponseMatrix[i][1].setText(trueString);
					userSubQuestionsResponseMatrix[i][1].setOnClickListener(radio_listener);
					userSubQuestionsResponseMatrix[i][1].setTag(UserResponse.TRUE);	
					userSubQuestionsResponseMatrix[i][1].setTextColor(Color.WHITE);
					userSubQuestionsResponseMatrix[i][1].setEnabled(true);
					subQuestionRadioGroupList[i].addView(userSubQuestionsResponseMatrix[i][1]);

					userSubQuestionsResponseMatrix[i][2] = new RadioButton(this);
					userSubQuestionsResponseMatrix[i][2].setText(falseString);
					userSubQuestionsResponseMatrix[i][2].setOnClickListener(radio_listener);
					userSubQuestionsResponseMatrix[i][2].setTag(UserResponse.FALSE);
					userSubQuestionsResponseMatrix[i][2].setTextColor(Color.WHITE);
					userSubQuestionsResponseMatrix[i][2].setEnabled(true);
					subQuestionRadioGroupList[i].addView(userSubQuestionsResponseMatrix[i][2]);

					if(sq.getUserResponse() == UserResponse.NOT_AVAILABE){

						subQuestionRadioGroupList[i].check(userSubQuestionsResponseMatrix[i][0].getId());

					} else if(sq.getUserResponse() == UserResponse.TRUE){

						subQuestionRadioGroupList[i].check(userSubQuestionsResponseMatrix[i][1].getId());

						userSubQuestionsResponseMatrix[i][0].setEnabled(false);
						userSubQuestionsResponseMatrix[i][1].setEnabled(false);
						userSubQuestionsResponseMatrix[i][2].setEnabled(false);

						if(sq.isResponse()){

							userSubQuestionsResponseMatrix[i][1].setTextColor(Color.GREEN);

						} else userSubQuestionsResponseMatrix[i][1].setTextColor(Color.RED);

					} else if(sq.getUserResponse() == UserResponse.FALSE){

						subQuestionRadioGroupList[i].check(userSubQuestionsResponseMatrix[i][2].getId());

						userSubQuestionsResponseMatrix[i][0].setEnabled(false);
						userSubQuestionsResponseMatrix[i][1].setEnabled(false);
						userSubQuestionsResponseMatrix[i][2].setEnabled(false);

						if(!sq.isResponse()){

							userSubQuestionsResponseMatrix[i][2].setTextColor(Color.GREEN);

						} else userSubQuestionsResponseMatrix[i][2].setTextColor(Color.RED);
					}

				}
			}

			/*
			 * TODO Disegnare in  xml
			 * 
			 */
			
			// TODO : externaliza
			Typeface tf = Typeface.createFromAsset(getAssets(), "ASTRO867.TTF");

			
			// buttons
			LinearLayout buttonLinearLayout = new LinearLayout(this);
			buttonLinearLayout.setOrientation(LinearLayout.HORIZONTAL);
			buttonLinearLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
	                LayoutParams.WRAP_CONTENT));
						
			mainLinearLayout.addView(buttonLinearLayout);

			
			previousButton = new Button(this);
			previousButton.setTypeface(tf);
			previousButton.setTextColor(Color.rgb(3, 96, 176));			// TODO : externaliza
			
			previousButton.setText("PRECEDENTE"); // TODO externalize
			buttonLinearLayout.addView(previousButton);
			if(mainQuestionPreviousStack.isEmpty()) previousButton.setEnabled(false);
			else previousButton.setEnabled(true);
			previousButton.setOnClickListener(previousButtonOnClickHandler);
						
			nextButton = new Button(this);
			nextButton.setText("  PROSSIMA  "); // TODO exteranalize		
			nextButton.setTypeface(tf);
			nextButton.setTextColor(Color.rgb(3, 96, 176));			// TODO : externaliza
			buttonLinearLayout.addView(nextButton);
			nextButton.setEnabled(true);
			nextButton.setOnClickListener(nextButtonOnClickHandler);

		}
	}

	private void onNextButtonClick(View v) {

		nextButton.setEnabled(false);

		mainQuestionPreviousStack.push(mainQuestion);

		questionCounter++;
		
		if(isNewQuestion()){

			
			mainQuestion = loadNextMainQuestion();

			if(mainQuestion != null){
				ArrayList<SubQuestion> subQuestionList = mainQuestion.getSubQuestions();
				if (subQuestionList != null) noResponseCounter += subQuestionList.size();
			}

		} else {

			mainQuestion = mainQuestionNextStack.pop();

		}		

		createUserInterface();

		mainScrollView.invalidate();

	}

	private void onPreviousButtonClick(View v) {

		questionCounter--;
		
		previousButton.setEnabled(false);

		mainQuestionNextStack.push(mainQuestion);

		mainQuestion = mainQuestionPreviousStack.pop();

		createUserInterface();

		mainScrollView.invalidate();

	}

	private void onRadioButtonClick(View v) {

		RadioGroup radioGroup  = (RadioGroup) v.getParent();
		SubQuestion subQuestion = (SubQuestion) radioGroup.getTag();

		UserResponse userResponse = (UserResponse) v.getTag();
		subQuestion.setUserResponse(userResponse);

		int count = radioGroup.getChildCount(); // 3: NA, TRUE, FALSE

		// reset bg color
		for (int i = 0; i < count; i++) {
			((RadioButton) radioGroup.getChildAt(i)).setTextColor(Color.WHITE);
		}

		// OK
		if (
				(userResponse == UserResponse.TRUE  &&  subQuestion.isResponse()) || 
				(userResponse == UserResponse.FALSE && !subQuestion.isResponse())
				){
			((RadioButton) v).setTextColor(Color.GREEN);
			for (int i = 0; i < count; i++) {
				((RadioButton) radioGroup.getChildAt(i)).setEnabled(false);
			}

			noResponseCounter--;
			successCounter++;			
		}

		// KO
		else if (
				(userResponse == UserResponse.TRUE  && !subQuestion.isResponse()) || 
				(userResponse == UserResponse.FALSE && subQuestion.isResponse())
				){
			((RadioButton) v).setTextColor(Color.RED);
			for (int i = 0; i < count; i++) {
				((RadioButton) radioGroup.getChildAt(i)).setEnabled(false);
			}

			noResponseCounter--;
			failsCounter++;			
		}
		
		// TODO: esternalizzare
		failsCounterTextView.setText("ERRORI : " + String.valueOf(failsCounter));
		
		successCounterTextView.setText("ESATTE : " + String.valueOf(successCounter));
		
		noResponseCounterTextView.setText("NON RISPOSTE : " + String.valueOf(noResponseCounter));
		
		String idQuestion = mainQuestion == null ? "" :  String.valueOf(mainQuestion.getId());  
		idQuestionTextView.setText("ID DOMANDA : " + idQuestion);
		
		questionCounterTextView.setText("DOMANDA NUMERO : " + String.valueOf(questionCounter));
	}

	private Runnable updateTimeTask = new Runnable() {

		/**
		 * Chronometer start time.
		 */
		private final long start = SystemClock.uptimeMillis() + 2000; // TODO remove magic number :)

		public void run() {

			long millis = SystemClock.uptimeMillis() - start;
			int seconds = (int) (millis / 1000);
			elapsedTime = seconds;
			int minutes = seconds / 60;
			seconds     = seconds % 60;

			if (seconds < 10) {
				chronoTextView.setText("" + minutes + ":0" + seconds);
			} else {
				chronoTextView.setText("" + minutes + ":" + seconds);            
			}

			timerHandler.postAtTime(this,
					start + (((minutes * 60) + seconds + 1) * 1000));

			if(maxTimeInSeconds != -1 && elapsedTime >= maxTimeInSeconds) startActivity(getNextIntent());
		}
	};

	/* (non-Javadoc)
	 * @see android.app.Activity#onStop()
	 */
	@Override
	protected void onStop() {
		super.onStop();

		timerHandler.removeCallbacks(updateTimeTask);

	}

	/**
	 * Get the current Activity Context. Standard implementation is: return  ActivityName.this
	 * @return
	 */
	protected abstract Context getContext();
	
	/**
	 * Extras bundle to pass data between QuizActivity spezialization and the ResultActivity.
	 * 
	 */
	protected abstract ArrayList<String> getResults();
	
	/**
	 * Set the next intent
	 */
	private final Intent getNextIntent() {
		Intent intent = new Intent();
		intent.setClass(getContext(), ResultActivity.class);
		Bundle bundle = new Bundle();
		ArrayList<String> results = getResults();
		int key = 0;
		for (String value : results) {
			bundle.putString(String.valueOf(key), value);
			key++;
		}
		
		intent.putExtras(bundle);
		return intent;
	}

	/**
	 * @return the failsCounter
	 */
	public long getFailsCounter() {
		return failsCounter;
	}

	/**
	 * @return the successCounter
	 */
	public long getSuccessCounter() {
		return successCounter;
	}

	/**
	 * @return the noResponseCounter
	 */
	public long getNoResponseCounter() {
		return noResponseCounter;
	}

	
}